<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
	<title>webgrind</title>
	<link rel="stylesheet" type="text/css" href="styles/style.css" />
	<script src="js/jquery.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/jquery.blockUI.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/jquery.tablesorter.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/jquery.selectboxes.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/sprintf.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript" charset="utf-8">
		var fileUrlFormat = '<?php echo Webgrind_Config::$fileUrlFormat?>';
		var currentDataFile = null;
		var callInfoLoaded = new Array();
		function getOptions(){
			options = new Object();
			options.dataFile = $("#dataFile").val();
			options.costFormat = $('#costFormat').val();
			options.showFraction = $("#showFraction").val();
			options.hideInternals = $('#hideInternals').attr('checked') ? 1 : 0;
			return options;
		}
		
		function update(){
			vars = getOptions();
			vars.op = 'function_list';
			$.getJSON("index.php",
				vars,
				function(data){
					callInfoLoaded = new Array();
					$("#function_table tbody").empty();
					for(i=0;i<data.functions.length;i++){
						callInfoLoaded[data.functions[i].nr] = false;
						$("#function_table tbody").append(functionTableRow(data.functions[i]));
					}
					currentDataFile = data.dataFile;
					$("#data_file").html(data.dataFile);
					$("#invoke_url").html(data.invokeUrl);
					$("#mtime").html(data.mtime);
					$("#shown_sum").html(data.functions.length);
					$("#invocation_sum").html(data.summedInvocationCount);
					$("#runtime_sum").html(data.summedRunTime);
					
					$("#hello_message").hide();
					$("#trace_view").show();
					
					$("#function_table").trigger('update');
					$("#function_table").trigger("sorton",[[[3,1]]]); 
				}
			);
		}
		
		function reloadFilelist(){
			$.getJSON("index.php",
				{'op':'file_list'},
				function(data){
					options = new Object();
					for(i=0;i<data.length;i++){
						options[data[i]['filename']] = data[i]['invokeUrl']+' ('+data[i]['filename']+')';
					}
					$("#dataFile").removeOption(/[^0]/);
					$("#dataFile").addOption(options, false);

				}
			);
		}
		
		function loadCallInfo(functionNr){			
			$.getJSON("index.php",
				{'op':'callinfo_list', 'file':currentDataFile, 'functionNr':functionNr, 'costFormat':$("#costFormat").val()},
				function(data){
					
					if(data.calledByHost)
						$("#callinfo_area_"+functionNr).append('<b>Called from script host</b>');
					
					insertCallInfo(functionNr, 'sub_calls_table_', 'Calls', data.subCalls);
					insertCallInfo(functionNr, 'called_from_table_', 'Called From', data.calledFrom);

					
					callInfoLoaded[functionNr] = true;
				}
			);				
		
		}
		
		function insertCallInfo(functionNr, idPrefix, title, data){
			if(data.length==0)
				return;
				
			$("#callinfo_area_"+functionNr).append(callTable(functionNr,idPrefix, title));
			
			for(i=0;i<data.length;i++){
				$("#"+idPrefix+functionNr+" tbody").append(callTableRow(i, data[i]));
			}
			
			$("#"+idPrefix+functionNr).tablesorter({
				widgets: ['zebra'],
				headers: { 
		            3: { 
		                sorter: false 
		            }
		        }							
			});
			$("#"+idPrefix+functionNr).bind("sortStart",sortBlock).bind("sortEnd",$.unblockUI);
			$("#"+idPrefix+functionNr).trigger("sorton",[[[2,1]]]); 				
				
			
		}
		
		function callTable(functionNr, idPrefix, title){
			return '<table class="tablesorter" id="'+idPrefix+functionNr+'" cellspacing="0"> \
						<thead><tr><th>'+title+'</th><th>Count</th><th>Total Call Cost</th><th> </th></tr></thead> \
						<tbody> \
						</tbody> \
					</table> \
			';
		}
		
		function callTableRow(nr,data){
			return '<tr> \
						<td>'+data.callerFunctionName+' @ '+data.line+'</td> \
						<td class="nr">'+data.callCount+'</td> \
						<td class="nr">'+data.summedCallCost+'</td> \
						<td><a title="Open file and show line" href="'+sprintf(fileUrlFormat,data.callerFile,data.line)+'" target="_blank"><img src="img/file_line.png" alt="O"/></a></td> \
					</tr>';
			
		}
				
		function toggleCallInfo(functionNr){
			if(!callInfoLoaded[functionNr]){
				loadCallInfo(functionNr);
			}					
			
			$("#callinfo_area_"+functionNr).toggle();
			current = $("#fold_marker_"+functionNr).get(0).src;
			if(current.substr(current.lastIndexOf('/')+1) == 'right.gif')
				$("#fold_marker_"+functionNr).get(0).src = 'img/down.gif';
			else
				$("#fold_marker_"+functionNr).get(0).src = 'img/right.gif';
		}
		
		function functionTableRow(data){
			openLink = (data.file=='php:internal')?'':'<a title="Open file" href="'+sprintf(fileUrlFormat,data.file,-1)+'" target="_blank"><img src="img/file.png" alt="O"/></a>';
			return '<tr> \
						<td> \
							<a href="javascript:toggleCallInfo('+data.nr+')"> \
								<img id="fold_marker_'+data.nr+'" src="img/right.gif" />&nbsp;&nbsp;'+data.functionName+' \
							</a> \
							<div class="callinfo_area" id="callinfo_area_'+data.nr+'"></div> \
						</td> \
						<td>'+openLink+'</td> \
						<td class="nr">'+data.invocationCount+'</td> \
						<td class="nr">'+data.summedSelfCost+'</td> \
						<td class="nr">'+data.summedInclusiveCost+'</td> \
					</tr> \
			';
		}
		
		function sortBlock(){
			$.blockUI('<div class="block_box"><h1>Sorting...</h1></div>');
		}
		
		
		$(document).ready(function() { 
			$.blockUI.defaults.pageMessage = '<div class="block_box"><h1>Loading...</h1><p>Loading information from server. If the callgrind file is large this may take some time.</p></div>';
			$.blockUI.defaults.overlayCSS =  { backgroundColor: '#fff', opacity: '0' }; 
			$.blockUI.defaults.fadeIn = 0;
			$.blockUI.defaults.fadeOut = 0;
			$().ajaxStart($.blockUI).ajaxStop($.unblockUI);
			$("#function_table").tablesorter({
				widgets: ['zebra'],
				sortInitialOrder: 'desc',
				headers: { 
		            1: { 
		                sorter: false 
		            }
		        }
			});
			$("#function_table").bind("sortStart",sortBlock).bind("sortEnd",$.unblockUI);
		});
		
	</script>
</head>
<body>
<div id="head">
    <h1>webgrind<sup style="font-size:10px">v0.6</sup></h1>
    <p>profiling in the browser</p>
</div>
<div id="options">
    <form method="get" onsubmit="update();return false">
    	<div style="float:right;margin-left:10px">
    	    <input type="submit" value="update" />
    	</div>
    	<div style="float:right;">
    		<label style="margin:0 5px">in</label>
    		<select id="costFormat" name="costFormat">
    		    <option value="percent" <?php echo (Webgrind_Config::$defaultCostformat=='percent') ? 'selected' : ''?>>percent</option>
    		    <option value="msec" <?php echo (Webgrind_Config::$defaultCostformat=='msec') ? 'selected' : ''?>>milliseconds</option>
    		    <option value="usec" <?php echo (Webgrind_Config::$defaultCostformat=='usec') ? 'selected' : ''?>>microseconds</option>
    		</select>
    	</div>
    	<div style="float:right;">
    		<label style="margin:0 5px">of</label>
    		<select id="dataFile" name="dataFile" style="width:200px">
    			<option value="0">Auto (newest)</option>
    			<?php foreach(Webgrind_FileHandler::getInstance()->getTraceList() as $trace):?>
    				<option value="<?php echo $trace['filename']?>"><?php echo $trace['invokeUrl']?> (<?php echo $trace['filename']?>)</option>
    			<?php endforeach;?>
    		</select>
			<img class="list_reload" src="img/reload.gif" onclick="reloadFilelist()"/>
    	</div>
    	<div style="float:right">
    		<label style="margin:0 5px">Show</label>
    		<select id="showFraction" name="showFraction">
    			<?php for($i=100; $i>0; $i-=10):?>
    			<option value="<?php echo $i/100?>" <?php if ($i==Webgrind_Config::$defaultFunctionPercentage):?>selected="selected"<?php endif;?>><?php echo $i?>%</option>
    			<?php endfor;?>
    		</select>
    	</div>
    	<div style="clear:both;"></div>    	
    	<div style="margin:0 45px">
    	    <input type="checkbox" name="hideInternals" value="1" <?php echo (Webgrind_Config::$defaultHideInternalFunctions==1) ? 'checked' : ''?> id="hideInternals">
    	    <label for="hideInternals">Hide PHP functions</label>
    	</div>
    </form>
</div>
<div style="clear:both;"></div>
<div class="hr"></div>
<div id="trace_view">
	<h2 id="invoke_url"></h2>
	<div style="float:left;">
	    <span id="data_file"></span> @ <span id="mtime"></span>
	</div>
	<div style="float:right;">
	    <span id="invocation_sum"></span> different functions called in <span id="runtime_sum"></span> milliseconds (<span id="shown_sum"></span> shown)
	</div>
	<div style="clear:both"></div>
	<table class="tablesorter" id="function_table" cellspacing="0">
		<thead><tr><th>Function</th><th> </th><th>Invocation Count</th><th>Total Self Cost</th><th>Total Inclusive Cost</th></tr></thead>
		<tbody>
		</tbody>
	</table>
</div>
<h2 id="hello_message">Select a cachegrind file above</h2>
<div id="footer">
    Copyright © 2008 Jacob Oettinger &amp; Joakim Nygård. <a href="http://code.google.com/p/webgrind/">webgrind homepage</a>
</div>
</body>
</html>